package com.tang.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tang.constants.SystemConstants;
import com.tang.dto.AddArticleDto;
import com.tang.dto.ArticleDao;
import com.tang.sys.ResponseResult;
import com.tang.sys.entity.*;
import com.tang.sys.mapper.*;
import com.tang.sys.service.IArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tang.sys.service.IArticleTagService;
import com.tang.sys.service.ICategoryService;
import com.tang.sys.service.ITagService;
import com.tang.sys.vo.*;
import com.tang.utils.BeanCopyUtils;
import com.tang.utils.RedisCache;
import com.tang.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author shankaka
 * @since 2023-04-14
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Autowired
    private ICategoryService iCategoryService;

    @Autowired
    private IArticleService iArticleService;

    @Autowired
    private ITagService iTagService;
    @Resource
    private TagMapper tagMapper;
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private LinkMapper linkMapper;

    @Resource
    private ArticleTagsMapper articleTagsMapper;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UserServiceImpl userService;


    @Override
    public ResponseResult hotArticleList() {
        //查询热门文章 封装成ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //最多只查询10条
        Page<Article> page = new Page(1,10);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();

        //VO视图处理
        //bean
//        List<HotArticleVo> articleVos = new ArrayList<>();
//        for (Article article : articles) {
//            HotArticleVo vo = new HotArticleVo();
//            BeanUtils.copyProperties(article,vo);
//            articleVos.add(vo);
//        }
        List<HotArticleVo> vo = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);

        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Integer categoryId) {
        //查询条件
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //如果有categoryId就要查询时要传入相同
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0 ,Article::getCategoryId,categoryId);
        //状态时正式发布 置顶要显示在前面
        lambdaQueryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        //对isTop进行排序 desc
        lambdaQueryWrapper.orderByAsc(Article::getIsTop);
        //分页查询
        Page<Article> page = new Page<>(pageNum,5);
        page(page,lambdaQueryWrapper);
        //查询categoryName
        List<Article> articles = page.getRecords();
        //articleID 查询 categoryName
//        for (Article article : articles) {
//            Category category = iCategoryService.getById(article.getCategoryId());
//            article.setCategoryName(category.getName());
//
//        }
        articles.stream()
                .map(article -> {
                    Category category = iCategoryService.getById(article.getCategoryId());
                    article.setCategoryName(category.getName());
                    return article;
                })
                .collect(Collectors.toList());

        //封装查询结果 vo
        List<articleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), articleListVo.class);

        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    //文章详情接口
    @Override
    public ResponseResult getArticleDetail(Long id) {
        //根据id查询详情页文章
        Article article = getById(id);
        //从redis中获取viewCount
        Integer viewCount = redisCache.getCacheMapValue("article:viewCount", id.toString());
        article.setViewCount(viewCount.longValue());
        //转换成vo
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        //根据分类id查询分类名
        Long categoryId = articleDetailVo.getCategoryId();
        Category category = iCategoryService.getById(categoryId);
        if (category != null){
            articleDetailVo.setCategoryName(category.getName());
        }
        //查询文章的标签
        Long id1 = article.getId();
        //查询文章对应的标签
        LambdaQueryWrapper<ArticleTags> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ArticleTags::getArticleId,id1);
        List<ArticleTags> articleTags = articleTagsMapper.selectList(wrapper);

        List<Long> articleTagList = new ArrayList<>();
        for (ArticleTags articleTag : articleTags) {
            articleTagList.add(articleTag.getTagId());
        }
        //查询标签对应的名字
        List<String> articleNameList = new ArrayList<>();
        if (articleTagList.size() > 0){
            LambdaQueryWrapper<Tag> tagWrapper = new LambdaQueryWrapper<>();
            tagWrapper.in(Tag::getId,articleTagList);
            List<Tag> tagList = tagMapper.selectList(tagWrapper);
            for (Tag tag : tagList) {
                articleNameList.add(tag.getName());
            }
        }

        //根据标签的id查询tag里面的name
        articleDetailVo.setTags(articleNameList);
        //封装成响应返回

        return ResponseResult.okResult(articleDetailVo);
    }



    //更新浏览数据
    @Override
    public ResponseResult updateViewCount(Long id) {
        //更新redis中对应的浏览量
        redisCache.incrementCacheMapValue("article:viewCount",id.toString(),1);
        return null;
    }
    //发布的最新文章排序
    @Override
    public ResponseResult newArticleList() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper();
        //必须是正式的文章
        queryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照时间的发布进行排序
        queryWrapper.orderByDesc(Article::getCreateTime);
        //最多只查询10条
        Page<Article> page = new Page(1,10);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();
        List<NewArticleVo> vo = BeanCopyUtils.copyBeanList(articles, NewArticleVo.class);
        return ResponseResult.okResult(vo);
    }


    @Override
    @Transactional
    public ResponseResult add(AddArticleDto articleDto) {
        //添加 博客
        Article article = BeanCopyUtils.copyBean(articleDto, Article.class);
        //article.setCreateTime(new Date());
        save(article);


//        List<ArticleTag> articleTags = articleDto.getTags().stream()
//                .map(tagId -> new ArticleTag(article.getId(), tagId))
//                .collect(Collectors.toList());

        if (null!= articleDto.getTags()){
            for (Long tag : articleDto.getTags()) {
                articleTagsMapper.insert(new ArticleTags(null,article.getId(),tag));
            }
        }

        //添加 博客和标签的关联
//        iArticleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }



    @Override
    public ResponseResult<PageVo> pageTagList(Integer pageNum, Integer pageSize, AddArticleDto addArticleDto) {
        //分页查询
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Article::getCreateTime);
        //wrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        wrapper.like(StringUtils.hasText(addArticleDto.getTitle()),Article::getTitle,addArticleDto.getTitle());
        wrapper.like(StringUtils.hasText(addArticleDto.getSummary()),Article::getSummary,addArticleDto.getSummary());

        Page<Article> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page,wrapper);

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());


        return ResponseResult.okResult(pageVo);
    }



    //删除文章
    @Override
    public ResponseResult<Article> deldeteArticle(Long id) {
        //获取id
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getId,id);
        this.baseMapper.delete(wrapper);

        return ResponseResult.okResult();
    }

    //文章总数
    @Override
    public ResponseResult getTotal() {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getStatus,SystemConstants.STATUS_NORMAL);
        Integer articleCount  = articleMapper.selectCount(wrapper);

        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(User::getStatus,SystemConstants.STATUS_NORMAL);
        Integer userCount  = userMapper.selectCount(userWrapper);

        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        commentWrapper.eq(Comment::getDelFlag,SystemConstants.COMMENT_DELFLAG);
        Integer commentCount = commentMapper.selectCount(commentWrapper);

        LambdaQueryWrapper<Link> linkWrapper = new LambdaQueryWrapper<>();
        linkWrapper.eq(Link::getStatus,SystemConstants.LINK_STATUS);
        Integer linkCount = linkMapper.selectCount(linkWrapper);

        LambdaQueryWrapper<Tag> tagWrapper = new LambdaQueryWrapper<>();
        tagWrapper.eq(Tag::getDelFlag,SystemConstants.TAG_DELFLAG);
        Integer tagCount = tagMapper.selectCount(tagWrapper);

        Map<String, Integer> countMap = new HashMap<>();
        countMap.put("articleCount", articleCount);
        countMap.put("userCount", userCount);
        countMap.put("commentCount",commentCount);
        countMap.put("linkCount",linkCount);
        countMap.put("tagCount",tagCount);

        ResponseResult responseResult = ResponseResult.okResult();
        responseResult.setData(countMap);
        return responseResult;
    }
    //获取文章的内容和分类和标签
    @Override
    public ResponseResult<ArticleDetailVo> getArticleInfo(Long id) {
        Article byId = iArticleService.getById(id);
        List<Long> tagIds = getTagIdsByArticleId(id);
        byId.setTags(tagIds);


        return ResponseResult.okResult(byId);
    }

    @Override
    public ResponseResult updateArticleDetail(Article article) {
        this.baseMapper.updateById(article);
        //删除原有的和标签
        LambdaQueryWrapper<ArticleTags> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ArticleTags::getArticleId,article.getId());
        articleTagsMapper.delete(wrapper);
        //新增标签
        if (null != article.getTags()){
            for (Long tag : article.getTags()) {
                articleTagsMapper.insert(new ArticleTags(null,article.getId(),tag));
            }
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateArticleStatus(Article article) {
        Article article1 = articleMapper.selectById(article.getId());
        article1.setStatus(article.getStatus());
        articleMapper.updateById(article1);
        return ResponseResult.okResult(200,"修改成功");
    }

    @Override
    public ResponseResult Blogadd(AddArticleDto blogarticledto) {
        // 添加博客
        Article Blogarticle = BeanCopyUtils.copyBean(blogarticledto, Article.class);

        // 设置博客状态为 "1"
        Blogarticle.setStatus("1");

        save(Blogarticle);

        if (null != blogarticledto.getTags()) {
            for (Long tag : blogarticledto.getTags()) {
                articleTagsMapper.insert(new ArticleTags(null, Blogarticle.getId(), tag));
            }
        }

        // 获取当前用户信息
        Long userId = SecurityUtils.getUserId();
        User byId = userService.getById(userId);

        // 检查用户积分是否足够扣除
        int requiredExp = 1000;
        int currentExp = Integer.parseInt(byId.getUserExp());

        if (currentExp >= requiredExp) {
            // 扣除积分
            int remainingExp = currentExp - requiredExp;
            byId.setUserExp(String.valueOf(remainingExp));
            userService.updateById(byId);

            return ResponseResult.okResult();
        } else {
            // 用户积分不足，返回错误信息
            return ResponseResult.errorResult(508, "用户积分不足");
        }
    }

    @Override
    public ResponseResult updateArticleThumbnail(Article article) {
        Article articleThumbnail = articleMapper.selectById(article.getId());
        articleThumbnail.setThumbnail(article.getThumbnail());


        articleMapper.updateById(articleThumbnail);

        return ResponseResult.okResult(200, "图片状态修改成功");
    }

    private List<Long> getTagIdsByArticleId(Long articleId) {
        LambdaQueryWrapper<ArticleTags> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ArticleTags::getTagId).eq(ArticleTags::getArticleId,articleId);
        List<ArticleTags> tagsList = articleTagsMapper.selectList(wrapper);

        List<Long> tagIdList = new ArrayList<>();
        for (ArticleTags tag : tagsList) {
            tagIdList.add(tag.getTagId());
        }
        return tagIdList;

    }

}
